package com.guijq.codesegment.tree;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

public class Tree<T> implements ITree {
    private HashMap<Integer, HashMap<Integer, TreeNodeBo>> treeNodesMap = new HashMap<>();
    private List<TreeNodeBo> treeNodesList = new ArrayList<TreeNodeBo>();

    public Tree(List<ITreeNode> list) {
        initTreeNodeMap(list);
        initTreeNodeList();
    }

    private void addToMap(TreeNodeBo treeNodeBo) {
        HashMap<Integer, TreeNodeBo> levelNodesMap = treeNodesMap.get(treeNodeBo.getLevel());
        if (null == levelNodesMap) {
            levelNodesMap = new HashMap<>();
            treeNodesMap.put(treeNodeBo.getLevel(), levelNodesMap);
        }
        if (levelNodesMap.containsKey(treeNodeBo.getNodeId())) {
            throw new RuntimeException();
        } else {
            levelNodesMap.put(treeNodeBo.getNodeId(), treeNodeBo);
        }
    }

    private void initTreeNodeMap(List<ITreeNode> list) {
        TreeNodeBo treeNodeBo = null;
        for (ITreeNode item : list) {
            treeNodeBo = new TreeNodeBo(item);
            addToMap(treeNodeBo);
        }
        //按级别一次绑定
        try {
            for (TreeNodeLevelEnum c : TreeNodeLevelEnum.values()) {
                HashMap<Integer, TreeNodeBo> levelTreeNodesMap = treeNodesMap.get(c.getCode());
                if (null != levelTreeNodesMap) {
                    Iterator<TreeNodeBo> iter = levelTreeNodesMap.values().iterator();
                    TreeNodeBo parentTreeNode = null;
                    while (iter.hasNext()) {
                        treeNodeBo = iter.next();
                        if (treeNodeBo.getParentNodeId() != null && treeNodeBo.getParentNodeId() != 0) {
                            //存在父id,
                            parentTreeNode = treeNodesMap.get(c.getCode()).get(treeNodeBo.getParentNodeId());
//                            treeNodeBo.setParent(parentTreeNode);
                            parentTreeNode.addChild(treeNodeBo);
                        } else if (treeNodeBo.getParentNodeId() == null && treeNodeBo.getParentLevelNodeId() != null) {
                            if (TreeNodeLevelEnum.existPreviousLevel(c.getCode())) {
                                parentTreeNode = treeNodesMap.get(TreeNodeLevelEnum.getPreviousLevel(c.getCode()).getCode()).get(treeNodeBo.getParentLevelNodeId());
//                                treeNodeBo.setParent(parentTreeNode);
                                parentTreeNode.addChild(treeNodeBo);
                            } else {
                                throw new RuntimeException("");
                            }
                        }
                    }
                }
            }
        } catch (Exception ex) {
            //树结构异常
            throw new RuntimeException();
        }
    }

    private void initTreeNodeList() {
        if (treeNodesList.size() > 0) {
            return;
        }
        if (treeNodesMap.size() == 0) {
            return;
        }


        HashMap<Integer, TreeNodeBo> levelTreeNodesMap = treeNodesMap.get(TreeNodeLevelEnum.FIRST.getCode());
        if (null != levelTreeNodesMap) {
            Iterator<TreeNodeBo> iter = levelTreeNodesMap.values().iterator();
            TreeNodeBo treeNodeBo = null;
            while (iter.hasNext()) {
                treeNodeBo = iter.next();
                if (treeNodeBo.getParentNodeId()== null && treeNodeBo.getParentLevelNodeId() == null) {
                    this.treeNodesList.add(treeNodeBo);
                }
            }
        }


    }

    @Override
    public List<TreeNodeBo> getTree() {
        return this.treeNodesList;
    }

    @Override
    public List<TreeNodeBo> getRoot() {
        return treeNodesList;
    }

    @Override
    public TreeNodeBo getTreeNode(String nodeId, int level) {
        if (null != this.treeNodesMap.get(level)) {
            return this.treeNodesMap.get(level).get(nodeId);
        }
        return null;

    }
}
